<?php

declare(strict_types=1);

namespace App\CustHub\Model;

use App\Common\Constants\ErrorCode;
use App\CustHub\Amqp\Producers\SendRecordProducers;
use App\CustHub\Constants\SendConfigConstants;
use App\CustHub\Service\ChSendConfigService;
use App\CustHub\Service\CommonService;
use App\Enum\WordTypeEnum;
use App\Exception\BusinessException;
use Hyperf\Amqp\Producer;
use Hyperf\Di\Annotation\Inject;
use Mine\MineModel;

/**
 * @property int $id 主键
 * @property int $main_uid 主账号id
 * @property int $corp_id 主账号id
 * @property int $loop_id 循环任务id
 * @property int $uid 私域用户ID
 * @property string $title 标题
 * @property array $content 内容
 * @property string $msg_types 
 * @property int $group_id 分组id
 * @property int $send_type 1按客户/客户群发送   2按条件设置发送
 * @property int $open_custom 是否选择客户
 * @property int $open_crowd 是否选择群
 * @property int $task_type 1群消息  2群公告
 * @property int $crowd_type 1高级群发  2极速群发
 * @property array $custom_ids 客户ids
 * @property int $sort 
 * @property array $crowd_ids 客户群ids
 * @property array $condition_conf 条件配置
 * @property int $is_send_loss 是否发送流失用户
 * @property int $exception_type 异常设置 1全部失败暂停  2任意失败暂停
 * @property int $send_limit_type 1跟随全局间隔设置  2任务自定义间隔设置
 * @property array $send_limit_conf 间隔配置
 * @property int $send_times 发送时间 1立即发送  2单词定时 3每天循环  4每周循环  5每月循环
 * @property array $send_times_conf 时间配置
 * @property int $status -1 创建中 0等待中  1发送中  2已完成  3暂停中   4已取消  
 * @property int $is_loop 是否是循环任务
 * @property int $crowd_total 群数量
 * @property int $custom_total 客户数量
 * @property int $lose_total 流失数量
 * @property int $success_total 成功数量(未失败)
 * @property int $fail_total 失败数量
 * @property int $complete_total 完成数量
 * @property int $is_loop_end 循环是否截止
 * @property string $loop_end_time 结束时间
 * @property string $end_time 结束时间
 * @property string $start_time 开始时间
 * @property \Carbon\Carbon $created_at 
 * @property \Carbon\Carbon $updated_at 
 * @property string $date 
 * @property string $crowd_notice 群公告
 * @property string $speed_text 极速群发内容
 * @property-read mixed $msg_types_text 
 * @property-read null|ChCrowdSendingGroup $group 
 * @property-read null|ChCorp $corp 
 * @property-read null|ChUser $user 
 */
class ChCrowdSending extends MineModel
{

    #[Inject]
    protected ChSendConfigService $sendService;
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'ch_crowd_sending';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'main_uid', 'corp_id', 'loop_id', 'uid', 'title', 'content', 'msg_types', 'group_id', 'send_type', 'open_custom', 'open_crowd', 'task_type', 'crowd_type', 'custom_ids', 'sort', 'crowd_ids', 'condition_conf', 'is_send_loss', 'exception_type', 'send_limit_type', 'send_limit_conf', 'send_times', 'send_times_conf', 'status', 'is_loop', 'crowd_total', 'custom_total', 'lose_total', 'success_total', 'fail_total', 'complete_total', 'is_loop_end', 'loop_end_time', 'end_time', 'start_time', 'created_at', 'updated_at', 'date', 'crowd_notice', 'speed_text'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'main_uid' => 'integer', 'corp_id' => 'integer', 'loop_id' => 'integer', 'uid' => 'integer', 'content' => 'array', 'group_id' => 'integer', 'send_type' => 'integer', 'open_custom' => 'integer', 'open_crowd' => 'integer', 'task_type' => 'integer', 'crowd_type' => 'integer', 'custom_ids' => 'array', 'sort' => 'integer', 'crowd_ids' => 'array', 'condition_conf' => 'array', 'is_send_loss' => 'integer', 'exception_type' => 'integer', 'send_limit_type' => 'integer', 'send_limit_conf' => 'array', 'send_times' => 'integer', 'send_times_conf' => 'array', 'status' => 'integer', 'is_loop' => 'integer', 'crowd_total' => 'integer', 'custom_total' => 'integer', 'lose_total' => 'integer', 'success_total' => 'integer', 'fail_total' => 'integer', 'complete_total' => 'integer', 'is_loop_end' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
    protected array $appends = ['msg_types_text'];
    public function getMsgTypesTextAttribute()
    {
        if(empty($this -> getAttribute('msg_types'))) return "";
        $msgTypes = explode(",",$this -> getAttribute('msg_types'));
        $map = WordTypeEnum::getMap();
        $msgTypesText = [];
        foreach ($msgTypes as $type){
            $msgTypesText[] = $map[$type];
        }
        return $msgTypesText;
    }
    public function group()
    {
        return $this -> hasOne(ChCrowdSendingGroup::class,'id','group_id');
    }

    public function corp()
    {
        return $this -> hasOne(ChCorp::class,'id','corp_id');
    }


    public function user()
    {
        return $this -> hasOne(ChUser::class,'id','uid');
    }

    public static function saveCrowSending($uid,$mainUid,$data = [],$id = 0,$loopId = 0,$startTime = null)
    {
        $model = new self();
        $date = datetime(time(),'Ymd');
        if($loopId){
            $log = self::where('loop_id',$loopId) -> where('date',$date) -> first();
            if($log) return false;
        }
        if($id){
            $model = self::where('id',$id) -> first();
            if(empty($model)) throw new BusinessException(ErrorCode::NOT_ISSET,'数据不存在');
        }else{
            $model -> date = $date;
            $model -> sort = self::query() -> max('sort') + 1;
        }
        $model -> uid = $uid;
        $model -> main_uid = $mainUid;
        $model -> title = $data['title'];
        $model -> group_id = $data['group_id'] ?? 0;
        if(!empty($data['content'])){
            !is_array($data['content']) && $data['content'] = json_decode($data['content'],true);
        }
        $model -> send_type = $data['send_type'];
        $model -> task_type = $data['task_type'];
        $model -> corp_id = !empty($data['corp_id'])?$data['corp_id']:0;
        $model -> crowd_type = $data['crowd_type'];
        $model -> is_send_loss = $data['is_send_loss'];
        $info = CommonService::formatMsgContent($data['content']);
        if( $model -> task_type == 2){
            $model -> crowd_notice = $data['crowd_notice'];
            array_unshift($info['content'],['content'=>$data['crowd_notice'],'msg_type'=>'notice']);
        }

        $model -> content = $info['content'];
        $model -> msg_types = $info['msg_types'];
        //发送对象类型
        if($model -> send_type == 1){
            !empty($data['crowd_ids']) && $model -> crowd_ids =  !is_array($data['crowd_ids']) ? json_decode($data['crowd_ids'],true):$data['crowd_ids'];
            !empty($data['custom_ids']) && $model -> custom_ids = !is_array($data['custom_ids']) ? json_decode($data['custom_ids'],true):$data['custom_ids'];
        }else if($model -> send_type == 2){
            !empty($data['condition_conf']) && $model -> condition_conf = !is_array($data['condition_conf']) ? json_decode($data['condition_conf'],true):$data['condition_conf'];
        }
        if($model -> crowd_type == 1){
            //高级群发
            $model -> exception_type = $data['exception_type'];
            $model -> send_limit_type = $data['send_limit_type'];
            $model -> send_limit_conf = !is_array($data['send_limit_conf']) ? json_decode($data['send_limit_conf'],true):$data['send_limit_conf'];
        }else{
            //极速群发
            $model -> exception_type = 1;
            $model -> send_limit_conf = null;
            $model -> send_limit_type = null;
            $model -> speed_text = !empty($data['speed_text'])?$data['speed_text']:'';
        }
        $model -> send_times = $data['send_times'];
        $model -> is_loop = 0;
        !empty($data['send_times_conf']) && $model -> send_times_conf = !is_array($data['send_times_conf']) ? json_decode($data['send_times_conf'],true):$data['send_times_conf'];
        if(!in_array($model -> send_times,[1,2])){
            $model -> is_loop = 1;
            $model -> start_time = $startTime;
        }else{
            $model -> send_times == 1 && $model -> start_time = date("Y-m-d H:i:s",time());
            $model -> send_times == 2 && $model -> start_time = $model -> send_times_conf['time'];
        }
        $model -> is_loop_end = !empty($data['is_loop_end']) ?$data['is_loop_end']: 0;
        $model -> loop_end_time = !empty($data['loop_end_time']) ?$data['loop_end_time']: null;
        if($loopId){
            $model -> loop_id = $loopId;
            $model -> start_time = datetime(time(),'Y-m-d H:i:s');
        }
        $model -> save();
        return $model;
    }
}
